home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / russell / gc32.lha / gc.h < prev    next >
C/C++ Source or Header  |  1993-07-29  |  16KB  |  370 lines

  1. /* 
  2.  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
  3.  * Copyright (c) 1991 by Xerox Corporation.  All rights reserved.
  4.  *
  5.  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
  6.  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
  7.  *
  8.  * Permission is hereby granted to copy this garbage collector for any purpose,
  9.  * provided the above notices are retained on all copies.
  10.  */
  11.  
  12. #ifndef GC_H
  13.  
  14. # define GC_H
  15.  
  16. # include <stddef.h>
  17.  
  18. /* Define word and signed_word to be unsigned and signed types of the     */
  19. /* size as char * or void *.  There seems to be no way to do this    */
  20. /* even semi-portably.  The following is probably no better/worse     */
  21. /* than almost anything else.                        */
  22. /* The ANSI standard suggests that size_t and ptr_diff_t might be     */
  23. /* better choices.  But those appear to have incorrect definitions    */
  24. /* on may systems.  Notably "typedef int size_t" seems to be both    */
  25. /* frequent and WRONG.                            */
  26. typedef unsigned long GC_word;
  27. typedef long GC_signed_word;
  28.  
  29. /* Public read-only variables */
  30.  
  31. extern GC_word GC_heapsize;       /* Heap size in bytes */
  32.  
  33. extern GC_word GC_gc_no;/* Counter incremented per collection.      */
  34.             /* Includes empty GCs at startup.        */
  35.             
  36. extern int GC_incremental;  /* Using incremental/generational collection. */
  37.  
  38.  
  39. /* Public R/W variables */
  40.  
  41. extern int GC_quiet;    /* Disable statistics output.  Only matters if    */
  42.             /* collector has been compiled with statistics    */
  43.             /* enabled.  This involves a performance cost,    */
  44.             /* and is thus not the default.            */
  45.  
  46. extern int GC_dont_gc;    /* Dont collect unless explicitly requested, e.g. */
  47.             /* beacuse it's not safe.              */
  48.  
  49. extern int GC_dont_expand;
  50.             /* Dont expand heap unless explicitly requested */
  51.             /* or forced to.                */
  52.  
  53. extern int GC_full_freq;    /* Number of partial collections between    */
  54.                 /* full collections.  Matters only if    */
  55.                 /* GC_incremental is set.            */
  56.             
  57. extern GC_word GC_non_gc_bytes;
  58.             /* Bytes not considered candidates for collection. */
  59.             /* Used only to control scheduling of collections. */
  60.  
  61. extern GC_word GC_free_space_divisor;
  62.             /* We try to make sure that we allocate at     */
  63.             /* least N/GC_free_space_divisor bytes between    */
  64.             /* collections, where N is the heap size plus    */
  65.             /* a rough estimate of the root set size.    */
  66.             /* Initially, GC_free_space_divisor = 4.    */
  67.             /* Increasing its value will use less space    */
  68.             /* but more collection time.  Decreasing it    */
  69.             /* will appreciably decrease collection time    */
  70.             /* at the expens of space.            */
  71.             /* GC_free_space_divisor = 1 will effectively    */
  72.             /* disable collections.                */
  73.             
  74. /* Public procedures */
  75. /*
  76.  * general purpose allocation routines, with roughly malloc calling conv.
  77.  * The atomic versions promise that no relevant pointers are contained
  78.  * in the object.  The nonatomic versions guarantee that the new object
  79.  * is cleared.  GC_malloc_stubborn promises that no changes to the object
  80.  * will occur after GC_end_stubborn_change has been called on the
  81.  * result of GC_malloc_stubborn. GC_malloc_uncollectable allocates an object
  82.  * that is scanned for pointers to collectable objects, but is not itself
  83.  * collectable.  GC_malloc_uncollectable and GC_free called on the resulting
  84.  * object implicitly update GC_non_gc_bytes appropriately.
  85.  */
  86. # ifdef __STDC__
  87.   extern void * GC_malloc(size_t size_in_bytes);
  88.   extern void * GC_malloc_atomic(size_t size_in_bytes);
  89.   extern void * GC_malloc_uncollectable(size_t size_in_bytes);
  90.   extern void * GC_malloc_stubborn(size_t size_in_bytes);
  91. # else
  92.   extern char * GC_malloc(/* size_in_bytes */);
  93.   extern char * GC_malloc_atomic(/* size_in_bytes */);
  94.   extern char * GC_malloc_uncollectable(/* size_in_bytes */);
  95.   extern char * GC_malloc_stubborn(/* size_in_bytes */);
  96. # endif
  97.  
  98. /* Explicitly deallocate an object.  Dangerous if used incorrectly.     */
  99. /* Requires a pointer to the base of an object.                */
  100. /* If the argument is stubborn, it should not be changeable when freed. */
  101. /* An object should not be enable for finalization when it is         */
  102. /* explicitly deallocated.                        */
  103. # ifdef __STDC__
  104.   extern void GC_free(void * object_addr);
  105. # else
  106.   extern void GC_free(/* object_addr */);
  107. # endif
  108.  
  109. /*
  110.  * Stubborn objects may be changed only if the collector is explicitly informed.
  111.  * The collector is implicitly informed of coming change when such
  112.  * an object is first allocated.  The following routines inform the
  113.  * collector that an object will no longer be changed, or that it will
  114.  * once again be changed.  Only nonNIL pointer stores into the object
  115.  * are considered to be changes.  The argument to GC_end_stubborn_change
  116.  * must be exacly the value returned by GC_malloc_stubborn or passed to
  117.  * GC_change_stubborn.  (In the second case it may be an interior pointer
  118.  * within 512 bytes of the beginning of the objects.)
  119.  * There is a performance penalty for allowing more than
  120.  * one stubborn object to be changed at once, but it is acceptable to
  121.  * do so.  The same applies to dropping stubborn objects that are still
  122.  * changeable.
  123.  */
  124. void GC_change_stubborn(/* p */);
  125. void GC_end_stubborn_change(/* p */);
  126.  
  127. /* Return a pointer to the base (lowest address) of an object given    */
  128. /* a pointer to a location within the object.                */
  129. /* Return 0 if displaced_pointer doesn't point to within a valid    */
  130. /* object.                                */
  131. # ifdef __STDC__
  132.   void * GC_base(void * displaced_pointer);
  133. # else
  134.   char * GC_base(/* char * displaced_pointer */);
  135. # endif
  136.  
  137. /* Given a pointer to the base of an object, return its size in bytes.    */
  138. /* The returned size may be slightly larger than what was originally    */
  139. /* requested.                                */
  140. # ifdef __STDC__
  141.   size_t GC_size(void * object_addr);
  142. # else
  143.   size_t GC_size(/* char * object_addr */);
  144. # endif
  145.  
  146. /* For compatibility with C library.  This is occasionally faster than    */
  147. /* a malloc followed by a bcopy.  But if you rely on that, either here    */
  148. /* or with the standard C library, your code is broken.  In my        */
  149. /* opinion, it shouldn't have been invented, but now we're stuck. -HB    */
  150. /* The resulting object has the same kind as the original.        */
  151. /* If the argument is stubborn, the result will have changes enabled.    */
  152. /* It is an error to have changes enabled for the original object.    */
  153. # ifdef __STDC__
  154.     extern void * GC_realloc(void * old_object, size_t new_size_in_bytes);
  155. # else
  156.     extern char * GC_realloc(/* old_object, new_size_in_bytes */);
  157. # endif
  158.  
  159.  
  160. /* Explicitly increase the heap size.    */
  161. /* Returns 0 on failure, 1 on success.  */
  162. extern int GC_expand_hp(/* number_of_4K_blocks */);
  163.  
  164. /* Clear the set of root segments */
  165. extern void GC_clear_roots();
  166.  
  167. /* Add a root segment */
  168. extern void GC_add_roots(/* low_address, high_address_plus_1 */);
  169.  
  170. /* Add a displacement to the set of those considered valid by the    */
  171. /* collector.  GC_register_displacement(n) means that if p was returned */
  172. /* by GC_malloc, then (char *)p + n will be considered to be a valid    */
  173. /* pointer to n.  N must be small and less than the size of p.        */
  174. /* (All pointers to the interior of objects from the stack are        */
  175. /* considered valid in any case.  This applies to heap objects and    */
  176. /* static data.)                            */
  177. /* Preferably, this should be called before any other GC procedures.    */
  178. /* Calling it later adds to the probability of excess memory        */
  179. /* retention.                                */
  180. void GC_register_displacement(/* n */);
  181.  
  182. /* Explicitly trigger a collection.     */
  183. void GC_gcollect();
  184.  
  185. /* Enable incremental/generational collection.    */
  186. /* Not advisable unless dirty bits are         */
  187. /* available or most heap objects are        */
  188. /* pointerfree(atomic) or immutable.        */
  189. /* Don't use in leak finding mode.        */
  190. void GC_enable_incremental();
  191.  
  192. /* Debugging (annotated) allocation.  GC_gcollect will check         */
  193. /* objects allocated in this way for overwrites, etc.            */
  194. # ifdef __STDC__
  195.   extern void * GC_debug_malloc(size_t size_in_bytes,
  196.                   char * descr_string, int descr_int);
  197.   extern void * GC_debug_malloc_atomic(size_t size_in_bytes,
  198.                          char * descr_string, int descr_int);
  199.   extern void * GC_debug_malloc_uncollectable(size_t size_in_bytes,
  200.                              char * descr_string, int descr_int);
  201.   extern void * GC_debug_malloc_stubborn(size_t size_in_bytes,
  202.                            char * descr_string, int descr_int);
  203.   extern void GC_debug_free(void * object_addr);
  204.   extern void * GC_debug_realloc(void * old_object,
  205.                     size_t new_size_in_bytes,
  206.                     char * descr_string, int descr_int);
  207. # else
  208.   extern char * GC_debug_malloc(/* size_in_bytes, descr_string, descr_int */);
  209.   extern char * GC_debug_malloc_atomic(/* size_in_bytes, descr_string,
  210.                         descr_int */);
  211.   extern char * GC_debug_malloc_uncollectable(/* size_in_bytes, descr_string,
  212.                         descr_int */);
  213.   extern char * GC_debug_malloc_stubborn(/* size_in_bytes, descr_string,
  214.                         descr_int */);
  215.   extern void GC_debug_free(/* object_addr */);
  216.   extern char * GC_debug_realloc(/* old_object, new_size_in_bytes,
  217.                           descr_string, descr_int */);
  218. # endif
  219. void GC_debug_change_stubborn(/* p */);
  220. void GC_debug_end_stubborn_change(/* p */);
  221. # ifdef GC_DEBUG
  222. #   define GC_MALLOC(sz) GC_debug_malloc(sz, __FILE__, __LINE__)
  223. #   define GC_MALLOC_ATOMIC(sz) GC_debug_malloc_atomic(sz, __FILE__, __LINE__)
  224. #   define GC_MALLOC_UNCOLLECTABLE(sz) GC_debug_malloc_uncollectable(sz, \
  225.                             __FILE__, __LINE__)
  226. #   define GC_REALLOC(old, sz) GC_debug_realloc(old, sz, __FILE__, \
  227.                                    __LINE__)
  228. #   define GC_FREE(p) GC_debug_free(p)
  229. #   define GC_REGISTER_FINALIZER(p, f, d, of, od) \
  230.     GC_register_finalizer(GC_base(p), GC_debug_invoke_finalizer, \
  231.                   GC_make_closure(f,d), of, od)
  232. #   define GC_MALLOC_STUBBORN(sz) GC_debug_malloc_stubborn(sz, __FILE__, \
  233.                                    __LINE__)
  234. #   define GC_CHANGE_STUBBORN(p) GC_debug_change_stubborn(p)
  235. #   define GC_END_STUBBORN_CHANGE(p) GC_debug_end_stubborn_change(p)
  236. # else
  237. #   define GC_MALLOC(sz) GC_malloc(sz)
  238. #   define GC_MALLOC_ATOMIC(sz) GC_malloc_atomic(sz)
  239. #   define GC_MALLOC_UNCOLLECTABLE(sz) GC_malloc_uncollectable(sz)
  240. #   define GC_REALLOC(old, sz) GC_realloc(old, sz)
  241. #   define GC_FREE(p) GC_free(p)
  242. #   define GC_REGISTER_FINALIZER(p, f, d, of, od) \
  243.     GC_register_finalizer(p, f, d, of, od)
  244. #   define GC_MALLOC_STUBBORN(sz) GC_malloc_stubborn(sz)
  245. #   define GC_CHANGE_STUBBORN(p) GC_change_stubborn(p)
  246. #   define GC_END_STUBBORN_CHANGE(p) GC_end_stubborn_change(p)
  247. # endif
  248.  
  249. /* Finalization.  Some of these primitives are grossly unsafe.        */
  250. /* The idea is to make them both cheap, and sufficient to build        */
  251. /* a safer layer, closer to PCedar finalization.            */
  252. /* The interface represents my conclusions from a long discussion    */
  253. /* with Alan Demers, Dan Greene, Carl Hauser, Barry Hayes,         */
  254. /* Christian Jacobi, and Russ Atkinson.  It's not perfect, and        */
  255. /* probably nobody else agrees with it.        Hans-J. Boehm  3/13/92    */
  256. # ifdef __STDC__
  257.   typedef void (*GC_finalization_proc)(void * obj, void * client_data);
  258. # else
  259.   typedef void (*GC_finalization_proc)(/* void * obj, void * client_data */);
  260. # endif
  261.     
  262. void GC_register_finalizer(/* void * obj,
  263.                   GC_finalization_proc fn, void * cd,
  264.                   GC_finalization_proc *ofn, void ** ocd */);
  265.     /* When obj is no longer accessible, invoke        */
  266.     /* (*fn)(obj, cd).  If a and b are inaccessible, and    */
  267.     /* a points to b (after disappearing links have been    */
  268.     /* made to disappear), then only a will be        */
  269.     /* finalized.  (If this does not create any new        */
  270.     /* pointers to b, then b will be finalized after the    */
  271.     /* next collection.)  Any finalizable object that    */
  272.     /* is reachable from itself by following one or more    */
  273.     /* pointers will not be finalized (or collected).    */
  274.     /* Thus cycles involving finalizable objects should    */
  275.     /* be avoided, or broken by disappearing links.        */
  276.     /* fn is invoked with the allocation lock held.  It may */
  277.     /* not allocate.  (Any storage it might need        */
  278.     /* should be preallocated and passed as part of cd.)     */
  279.     /* fn should terminate as quickly as possible, and    */
  280.     /* defer extended computation.                */
  281.     /* All but the last finalizer registered for an object  */
  282.     /* is ignored.                        */
  283.     /* Finalization may be removed by passing 0 as fn.    */
  284.     /* The old finalizer and client data are stored in    */
  285.     /* *ofn and *ocd.                    */ 
  286.     /* Fn is never invoked on an accessible object,        */
  287.     /* provided hidden pointers are converted to real     */
  288.     /* pointers only if the allocation lock is held, and    */
  289.     /* such conversions are not performed by finalization    */
  290.     /* routines.                        */
  291.  
  292. /* The following routine may be used to break cycles between    */
  293. /* finalizable objects, thus causing cyclic finalizable        */
  294. /* objects to be finalized in the correct order.  Standard    */
  295. /* use involves calling GC_register_disappearing_link(&p),    */
  296. /* where p is a pointer that is not followed by finalization    */
  297. /* code, and should not be considered in determining         */
  298. /* finalization order.                        */ 
  299. int GC_register_disappearing_link(/* void ** link */);
  300.     /* Link should point to a field of a heap allocated     */
  301.     /* object obj.  *link will be cleared when obj is    */
  302.     /* found to be inaccessible.  This happens BEFORE any    */
  303.     /* finalization code is invoked, and BEFORE any        */
  304.     /* decisions about finalization order are made.        */
  305.     /* This is useful in telling the finalizer that     */
  306.     /* some pointers are not essential for proper        */
  307.     /* finalization.  This may avoid finalization cycles.    */
  308.     /* Note that obj may be resurrected by another        */
  309.     /* finalizer, and thus the clearing of *link may    */
  310.     /* be visible to non-finalization code.          */
  311.     /* There's an argument that an arbitrary action should  */
  312.     /* be allowed here, instead of just clearing a pointer. */
  313.     /* But this causes problems if that action alters, or     */
  314.     /* examines connectivity.                */
  315.     /* Returns 1 if link was already registered, 0        */
  316.     /* otherwise.                        */
  317.     /* Only exists for backward compatibility.  See below:    */
  318. int GC_general_register_disappearing_link(/* void ** link, void * obj */);
  319.     /* A slight generalization of the above. *link is    */
  320.     /* cleared when obj first becomes inaccessible.  This    */
  321.     /* can be used to implement weak pointers easily and    */
  322.     /* safely. Typically link will point to a location    */
  323.     /* holding a disguised pointer to obj.  In this way    */
  324.     /* soft pointers are broken before any object        */
  325.     /* reachable from them are finalized.  Each link    */
  326.     /* May be registered only once, i.e. with one obj    */
  327.     /* value.  This was added after a long email discussion */
  328.     /* with John Ellis.                    */
  329. int GC_unregister_disappearing_link(/* void ** link */);
  330.     /* Returns 0 if link was not actually registered.    */
  331.     /* Undoes a registration by either of the above two    */
  332.     /* routines.                        */
  333.  
  334. /* Auxiliary fns to make finalization work correctly with displaced    */
  335. /* pointers introduced by the debugging allocators.            */
  336. # ifdef __STDC__
  337.     void * GC_make_closure(GC_finalization_proc fn, void * data);
  338.     void GC_debug_invoke_finalizer(void * obj, void * data);
  339. # else
  340.     char * GC_make_closure(/* GC_finalization_proc fn, char * data */);
  341.     void GC_debug_invoke_finalizer(/* void * obj, void * data */);
  342. # endif
  343.  
  344.     
  345. /* The following is intended to be used by a higher level    */
  346. /* (e.g. cedar-like) finalization facility.  It is expected    */
  347. /* that finalization code will arrange for hidden pointers to    */
  348. /* disappear.  Otherwise objects can be accessed after they    */
  349. /* have been collected.                        */
  350. # ifdef I_HIDE_POINTERS
  351. #   ifdef __STDC__
  352. #     define HIDE_POINTER(p) (~(size_t)(p))
  353. #     define REVEAL_POINTER(p) ((void *)(HIDE_POINTER(p)))
  354. #   else
  355. #     define HIDE_POINTER(p) (~(unsigned long)(p))
  356. #     define REVEAL_POINTER(p) ((char *)(HIDE_POINTER(p)))
  357. #   endif
  358.     /* Converting a hidden pointer to a real pointer requires verifying    */
  359.     /* that the object still exists.  This involves acquiring the      */
  360.     /* allocator lock to avoid a race with the collector.        */
  361.     typedef char * (*GC_fn_type)();
  362. #   ifdef __STDC__
  363.         void * GC_call_with_alloc_lock(GC_fn_type fn, void * client_data);
  364. #   else
  365.         char * GC_call_with_alloc_lock(/* GC_fn_type fn, char * client_data */);
  366. #   endif
  367. # endif
  368.  
  369. #endif
  370.